#include "AlgoritmoCaminoMinimo.h"

AlgoritmoCaminoMinimo::AlgoritmoCaminoMinimo(string origen, string destino){
	nombreOrigen = origen;
	nombreDestino = destino;
}

void AlgoritmoCaminoMinimo::ejecutar(){

	caminoEncontrado = false;

	string idOrigen = buscarID ( nombreOrigen );
	string idDestino = buscarID ( nombreDestino );

	vector<string> v;
	Persona * personaOrigen = new Persona( idOrigen, v );
	Persona personaDestino( idDestino, v );

	idPeliculasDestino.agregar( personaDestino.getIdPeliculas()  );

	idPersonasProcesadas.agregar( personaOrigen->getID() );
	colaPersonas.push( personaOrigen );

	while ( ( !colaPersonas.empty() ) && ( !caminoEncontrado ) ){
		procesar( colaPersonas.front() );
		delete colaPersonas.front();
		colaPersonas.pop();
	}

	if ( !caminoEncontrado )
		cout << "Las personas no se encuentran relacionadas de ninguna manera" << endl;
	else
	{
		while ( !colaPersonas.empty() )
		{
			delete colaPersonas.front();
			colaPersonas.pop();
		}
	}

}

void AlgoritmoCaminoMinimo::procesar(Persona * unaPersona){

	vector<string> * peliculas = unaPersona->getIdPeliculas();
	for( unsigned int i = 0; i < peliculas->size(); i++ ){

		if( !idPeliculasProcesadas.esta( peliculas->at(i) ) ){

			idPeliculasProcesadas.agregar( peliculas->at(i) );
			vector<string> rutaPelicula = unaPersona->getRutaAnterior();
			rutaPelicula.push_back( unaPersona->getNombre() );
			Pelicula * unaPelicula = new Pelicula( peliculas->at(i), rutaPelicula );

			if( idPeliculasDestino.esta( unaPelicula->getID() ) ){
				caminoEncontrado = true;
				emitirCamino( unaPelicula );
			}
			else
			{
				vector<string> * personasPelicula = unaPelicula->getIdPersonas();
				for( unsigned int j = 0 ; j < personasPelicula->size() ; j++){
					if ( !idPersonasProcesadas.esta( personasPelicula->at(j) ) ){
						idPersonasProcesadas.agregar( personasPelicula->at(j) );
						vector<string> rutaPersona = unaPelicula->getRutaAnterior();
						rutaPersona.push_back( unaPelicula->getNombre() );
						Persona * otraPersona = new Persona( personasPelicula->at(j), rutaPersona );
						colaPersonas.push( otraPersona );
					}
				}
			}

			delete unaPelicula;

		}

	}

}

void AlgoritmoCaminoMinimo::emitirCamino(Pelicula * unaPelicula){
	vector<string> nombres = unaPelicula->getRutaAnterior();
	nombres.push_back( unaPelicula->getNombre() );
	nombres.push_back( nombreDestino );

	for (int i = 0; i < ( nombres.size()-1 ) ; i += 2 ){
		cout << nombres.at(i) << " trabajó con " << nombres.at(i+2) << " en " << nombres.at(i+1) << endl;
	}

	cout << endl << "Grado de separación: " <<  (int) nombres.size()/2;

}


//METODO DE PRUEBA
string AlgoritmoCaminoMinimo::buscarID(string nombre){
	if (nombre == "Marlon Brando") return "1";
	if (nombre == "Bernardo Bertolucci") return "2";
	if (nombre == "Maria Schneider") return "3";
	if (nombre == "Ricardo Darín") return "5";
	if (nombre == "Vincent Gallo") return "9";
	if (nombre == "Rodrigo De la Serna") return "17";
	if (nombre == "Juan José Campanella") return "19";

	throw "NOMBRE NO ENCONTRADO";
}
//
